package com.lge.simpleeventhandler.modelinfoboard;

import com.lge.simpleeventhandler.Model;
import com.lge.simpleeventhandler.Resource;
import com.lge.simpleeventhandler.Schedule;
import com.lge.simpleeventhandler.dom.JDOMParser;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class ModelInformationBoard extends JPanel implements ActionListener, DocumentListener {
    private static final long serialVersionUID = 1L;

    private Model model = null;
    private IModelInformationUpdateListener modelInfoUpdateListener = null;

    // Variables for Model Info Panel
    private JTextField modelNameTextField = null;
    private JTextField projectNameTextField = null;
    private JTextField operatorNameTextField = null;
    private JTextField countryNameTextField = null;

    // Variables for Schedule Panel
    private JTable scheduleTable = null;
    private ScheduleTableModel defaultTableModel = null;

    // Variables for Chipset Path Panel
    private JTextField chipsetNameTextField = null;
    private JTextField chipsetDllPathTextField = null;

    // Variables for Binary Path Panel
    private JTextField dailyPathTextField = null;
    private JTextField modelPathTextField = null;
    private JTextField developerListPathTextField = null;

    // Constructors
    public ModelInformationBoard(IModelInformationUpdateListener modelInfoUpdateListener) {
        this(new Model(), modelInfoUpdateListener);
    }

    public ModelInformationBoard(Model model, IModelInformationUpdateListener modelInfoUpdateListener) {
        super();
        this.model = model;
        this.modelInfoUpdateListener = modelInfoUpdateListener;

        initComponent();
    }

    public void setModelInformationUpdateListener(IModelInformationUpdateListener modelInfoUpdateListener) {
        this.modelInfoUpdateListener = modelInfoUpdateListener;
    }

    // Member Methods
    public void initComponent() {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        add(getModelInformationPanel());
        add(getSchedulePanel());
        add(getChipsetPanel());
        add(getBinaryPanel());
        add(getSaveButton());
    }

    public JComponent getModelInformationPanel() {
        JPanel modelInformationPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 0));
        modelInformationPanel.setBorder(new TitledBorder(Resource.MODEL_INFO_BOARD_MODEL_INFO_TEXT));

        JPanel modelNamePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        JLabel modelNameLabel = new JLabel(Resource.MODEL_NAME_LABEL_TEXT);
        modelNameTextField = new JTextField(3);
        modelNameTextField.getDocument().addDocumentListener(this);
        if (model != null) {
            modelNameTextField.setText(model.getModelName());
        }
        modelNamePanel.add(modelNameLabel);
        modelNamePanel.add(modelNameTextField);

        JPanel projectNamePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        JLabel projectNameLabel = new JLabel(Resource.PROJECT_NAME_LABEL_TEXT);
        projectNameTextField = new JTextField(3);
        projectNameTextField.getDocument().addDocumentListener(this);
        if (model != null) {
            projectNameTextField.setText(model.getModelProject());
        }
        projectNamePanel.add(projectNameLabel);
        projectNamePanel.add(projectNameTextField);

        JPanel operatorNamePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        JLabel operatorNameLabel = new JLabel(Resource.OPERATOR_NAME_LABEL_TEXT);
        operatorNameTextField = new JTextField(3);
        operatorNameTextField.getDocument().addDocumentListener(this);
        if (model != null) {
            operatorNameTextField.setText(model.getModelOperator());
        }
        operatorNamePanel.add(operatorNameLabel);
        operatorNamePanel.add(operatorNameTextField);

        JPanel countryNamePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        JLabel countryNameLabel = new JLabel(Resource.COUNTRY_NAME_LABEL_TEXT);
        countryNameTextField = new JTextField(3);
        countryNameTextField.getDocument().addDocumentListener(this);
        if (model != null) {
            countryNameTextField.setText(model.getModelCountry());
        }
        countryNamePanel.add(countryNameLabel);
        countryNamePanel.add(countryNameTextField);

        modelInformationPanel.add(modelNamePanel);
        modelInformationPanel.add(projectNamePanel);
        modelInformationPanel.add(operatorNamePanel);
        modelInformationPanel.add(countryNamePanel);

        return modelInformationPanel;
    }

    public JComponent getSchedulePanel() {
        JPanel schedulePanel = new JPanel();
        schedulePanel.setLayout(new BoxLayout(schedulePanel, BoxLayout.Y_AXIS));
        schedulePanel.setBorder(new TitledBorder(Resource.MODEL_INFO_BOARD_SCHEDULE_TEXT));

        JPanel scheduleButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        JButton addButton = new JButton(Resource.ADD_BUTTON_STRING);
        addButton.setActionCommand(Resource.ADD_BUTTON_STRING);
        addButton.addActionListener(this);
        scheduleButtonPanel.add(addButton);

        JButton removeButton = new JButton(Resource.REMOVE_BUTTON_STRING);
        removeButton.setActionCommand(Resource.REMOVE_BUTTON_STRING);
        removeButton.addActionListener(this);
        scheduleButtonPanel.add(removeButton);

        defaultTableModel = new ScheduleTableModel(Resource.columnNames, 0);
        scheduleTable = new JTable(defaultTableModel);
        scheduleTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        scheduleTable.setPreferredScrollableViewportSize(new Dimension(getPreferredSize().width - 10, scheduleTable.getPreferredScrollableViewportSize().height));

        for (int i = 0; i < model.getScheduleListSize(); i++) {
            Schedule schedule = model.getModelScheduleItem(i);

            Object[] rowData = { schedule.getScheduleEvent(), schedule.getScheduleStart(), schedule.getScheduleEnd(), new Boolean(schedule.isScheduleFixed()), schedule.getScheduleBranch(), new Boolean(schedule.isScheduleBranchedout()), schedule.getScheduleRequestcollab() };
            defaultTableModel.addRow(rowData);
        }

        for (int i = 0; i < scheduleTable.getColumnCount(); i++) {
            int width = 10;

            switch (i) {
            case 0:
            case 3:
                width = 40;
                break;
            case 1:
            case 2:
                width = 50;
                break;
            case 4:
            case 5:
                width = 110;
                break;
            case 6:
                width = 160;
                break;
            default:
                width = 60;
                break;
            }

            scheduleTable.getColumnModel().getColumn(i).setMaxWidth(width);
            scheduleTable.getColumnModel().getColumn(i).setMinWidth(width);
            scheduleTable.getColumnModel().getColumn(i).setWidth(width);
        }

        JScrollPane scrollPane = new JScrollPane(scheduleTable);
        scrollPane.setPreferredSize(new Dimension(scrollPane.getPreferredSize().width, 100));

        schedulePanel.add(scheduleButtonPanel);
        schedulePanel.add(scrollPane);

        return schedulePanel;
    }

    public JComponent getChipsetPanel() {
        JPanel chipsetPanel = new JPanel(new GridLayout(0, 1, 0, -5));
        chipsetPanel.setBorder(new TitledBorder(Resource.MODEL_INFO_BOARD_CHIPSET_TEXT));

        JPanel chipsetNamePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        JLabel chipsetNameLabel = new JLabel(Resource.CHIPSET_NAME_LABEL_TEXT);
        chipsetNameLabel.setPreferredSize(new Dimension(95, chipsetNameLabel.getPreferredSize().height));
        chipsetNameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        chipsetNameTextField = new JTextField(10);
        chipsetNameTextField.setText(model.getChipsetName());
        chipsetNameTextField.getDocument().addDocumentListener(this);

        chipsetNamePanel.add(chipsetNameLabel);
        chipsetNamePanel.add(chipsetNameTextField);

        JPanel chipsetDllPathPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        JLabel chipsetDllPathLabel = new JLabel(Resource.CHIPSET_DLL_PATH_LABEL_TEXT);
        chipsetDllPathLabel.setPreferredSize(new Dimension(95, chipsetDllPathLabel.getPreferredSize().height));
        chipsetDllPathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        chipsetDllPathTextField = new JTextField(20);
        chipsetDllPathTextField.setText(model.getChipsetDllpath());
        chipsetDllPathTextField.getDocument().addDocumentListener(this);
        JButton goChipsetDllPathButton = new JButton(Resource.GO_BUTTON_STRING);
        goChipsetDllPathButton.setActionCommand(Resource.CHIPSET_DLL_PATH_LABEL_TEXT);
        goChipsetDllPathButton.addActionListener(this);

        JButton copyChipsetDllPathButton = new JButton(Resource.COPY_BUTTON_STRING);
        copyChipsetDllPathButton.setActionCommand(Resource.CHIPSET_DLL_PATH_LABEL_TEXT);
        copyChipsetDllPathButton.addActionListener(this);

        chipsetDllPathPanel.add(chipsetDllPathLabel);
        chipsetDllPathPanel.add(chipsetDllPathTextField);
        chipsetDllPathPanel.add(goChipsetDllPathButton);
        chipsetDllPathPanel.add(copyChipsetDllPathButton);

        chipsetPanel.add(chipsetNamePanel);
        chipsetPanel.add(chipsetDllPathPanel);

        return chipsetPanel;
    }

    public JComponent getBinaryPanel() {
        JPanel binaryPanel = new JPanel(new GridLayout(0, 1, 0, -5));
        binaryPanel.setBorder(new TitledBorder(Resource.MODEL_INFO_BOARD_BINARY_TEXT));

        // Daily Path Panel
        JPanel dailyPathPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        JLabel dailyPathLabel = new JLabel(Resource.BINARY_DAILY_PATH_LABEL_TEXT);
        dailyPathLabel.setPreferredSize(new Dimension(95, dailyPathLabel.getPreferredSize().height));
        dailyPathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        dailyPathTextField = new JTextField(20);
        dailyPathTextField.setText(model.getBinaryDailypath());
        dailyPathTextField.getDocument().addDocumentListener(this);
        JButton goDailyPathButton = new JButton(Resource.GO_BUTTON_STRING);
        goDailyPathButton.setActionCommand(Resource.BINARY_DAILY_PATH_LABEL_TEXT);
        goDailyPathButton.addActionListener(this);

        JButton copyDailyPathButton = new JButton(Resource.COPY_BUTTON_STRING);
        copyDailyPathButton.setActionCommand(Resource.BINARY_DAILY_PATH_LABEL_TEXT);
        copyDailyPathButton.addActionListener(this);

        dailyPathPanel.add(dailyPathLabel);
        dailyPathPanel.add(dailyPathTextField);
        dailyPathPanel.add(goDailyPathButton);
        dailyPathPanel.add(copyDailyPathButton);

        // Model Path Panel
        JPanel modelPathPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        JLabel modelPathLabel = new JLabel(Resource.BINARY_MODEL_PATH_LABEL_TEXT);
        modelPathLabel.setPreferredSize(new Dimension(95, modelPathLabel.getPreferredSize().height));
        modelPathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        modelPathTextField = new JTextField(20);
        modelPathTextField.setText(model.getBinaryModelpath());
        modelPathTextField.getDocument().addDocumentListener(this);
        JButton goModelPathButton = new JButton(Resource.GO_BUTTON_STRING);
        goModelPathButton.setActionCommand(Resource.BINARY_MODEL_PATH_LABEL_TEXT);
        goModelPathButton.addActionListener(this);

        JButton copyModelPathButton = new JButton(Resource.COPY_BUTTON_STRING);
        copyModelPathButton.setActionCommand(Resource.BINARY_MODEL_PATH_LABEL_TEXT);
        copyModelPathButton.addActionListener(this);

        modelPathPanel.add(modelPathLabel);
        modelPathPanel.add(modelPathTextField);
        modelPathPanel.add(goModelPathButton);
        modelPathPanel.add(copyModelPathButton);

        // Developer List Panel
        JPanel developerListPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        JLabel developerListPathLabel = new JLabel(Resource.BINARY_DEVELOPER_LIST_LABEL_TEXT);
        developerListPathLabel.setPreferredSize(new Dimension(95, developerListPathLabel.getPreferredSize().height));
        developerListPathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        developerListPathTextField = new JTextField(20);
        developerListPathTextField.setText(model.getBinaryDeveloperpath());
        developerListPathTextField.getDocument().addDocumentListener(this);
        JButton goDeveloperListPathButton = new JButton(Resource.GO_BUTTON_STRING);
        goDeveloperListPathButton.setActionCommand(Resource.BINARY_DEVELOPER_LIST_LABEL_TEXT);
        goDeveloperListPathButton.addActionListener(this);

        JButton copyDeveloperListPathButton = new JButton(Resource.COPY_BUTTON_STRING);
        copyDeveloperListPathButton.setActionCommand(Resource.BINARY_DEVELOPER_LIST_LABEL_TEXT);
        copyDeveloperListPathButton.addActionListener(this);

        developerListPanel.add(developerListPathLabel);
        developerListPanel.add(developerListPathTextField);
        developerListPanel.add(goDeveloperListPathButton);
        developerListPanel.add(copyDeveloperListPathButton);

        binaryPanel.add(dailyPathPanel);
        binaryPanel.add(modelPathPanel);
        binaryPanel.add(developerListPanel);

        return binaryPanel;
    }

    public JComponent getSaveButton() {
        JButton saveButton = new JButton(Resource.FILE_SAVE_MENU_STRING);
        saveButton.setActionCommand(Resource.FILE_SAVE_MENU_STRING);
        saveButton.addActionListener(this);

        return saveButton;
    }

    // Callback Methods
    @Override
    public void actionPerformed(ActionEvent event) {
        String textFieldString = "";

        if (event.getActionCommand().equals(Resource.BINARY_DAILY_PATH_LABEL_TEXT)) {
            textFieldString = dailyPathTextField.getText();
        } else if (event.getActionCommand().equals(Resource.BINARY_MODEL_PATH_LABEL_TEXT)) {
            textFieldString = modelPathTextField.getText();
        } else if (event.getActionCommand().equals(Resource.BINARY_DEVELOPER_LIST_LABEL_TEXT)) {
            textFieldString = developerListPathTextField.getText();
        } else if (event.getActionCommand().equals(Resource.CHIPSET_DLL_PATH_LABEL_TEXT)) {
            textFieldString = chipsetDllPathTextField.getText();
        } else if (event.getActionCommand().equals(Resource.FILE_SAVE_MENU_STRING)) {
            saveButtonPressed();
        } else if (event.getActionCommand().equals(Resource.ADD_BUTTON_STRING)) {
            addButtonPressed();
        } else if (event.getActionCommand().equals(Resource.REMOVE_BUTTON_STRING)) {
            removeButtonPressed();
        }

        if (((JButton)event.getSource()).getText().equals(Resource.GO_BUTTON_STRING)) {
            try {
                if (textFieldString.trim().length() > 0) {
                    Runtime.getRuntime().exec("explorer " + textFieldString);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (((JButton)event.getSource()).getText().equals(Resource.COPY_BUTTON_STRING)) {
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(textFieldString), null);
        }
    }

    @Override
    public void insertUpdate(DocumentEvent event) {
        modelInfoUpdateListener.modelInfoTextChanged(event);
    }

    @Override
    public void removeUpdate(DocumentEvent event) {
        modelInfoUpdateListener.modelInfoTextChanged(event);
    }

    @Override
    public void changedUpdate(DocumentEvent event) {
        modelInfoUpdateListener.modelInfoTextChanged(event);
    }

    public void saveButtonPressed() {
        updateModel();

        JDOMParser.removeModelElement(model);
        JDOMParser.addModelElement(model);

        modelInfoUpdateListener.modelInfoBoardSaveFinished(model);
    }

    public void addButtonPressed() {
        Object[] rowData = { "", "", "", false, "", false, "" };
        defaultTableModel.addRow(rowData);

        modelInfoUpdateListener.modelInfoScheduleChanged();
    }

    public void removeButtonPressed() {
        if (scheduleTable.getSelectedRow() != -1) {
            defaultTableModel.removeRow(scheduleTable.getSelectedRow());
            
            modelInfoUpdateListener.modelInfoScheduleChanged();
        }
    }

    public void updateModel() {
        model.setModelName(modelNameTextField.getText());
        model.setModelProject(projectNameTextField.getText());
        model.setModelOperator(operatorNameTextField.getText());
        model.setModelCountry(countryNameTextField.getText());

        model.setScheduleList(getScheduleListFromUI());

        model.setChipsetName(chipsetNameTextField.getText());
        model.setChipsetDllpath(chipsetDllPathTextField.getText());

        model.setBinaryDailypath(dailyPathTextField.getText());
        model.setBinaryModelpath(modelPathTextField.getText());
        model.setBinaryDeveloperpath(developerListPathTextField.getText());
    }

    public ArrayList<Schedule> getScheduleListFromUI() {
        ArrayList<Schedule> scheduleListFromUI = new ArrayList<Schedule>();
        
        for (int i=0; i<scheduleTable.getRowCount(); i++) {
            Schedule schedule = new Schedule();
            
            schedule.setScheduleEvent((String)defaultTableModel.getValueAt(i, 0));
            schedule.setScheduleStart((String)defaultTableModel.getValueAt(i, 1));
            schedule.setScheduleEnd((String)defaultTableModel.getValueAt(i, 2));
            schedule.setScheduleFixed((Boolean)defaultTableModel.getValueAt(i, 3));
            schedule.setScheduleBranch((String)defaultTableModel.getValueAt(i, 4));
            schedule.setScheduleBranchedout((Boolean)defaultTableModel.getValueAt(i, 5));
            schedule.setScheduleRequestcollab((String)defaultTableModel.getValueAt(i, 6));
            schedule.setScheduleVersion((String)defaultTableModel.getValueAt(i, 7));
            
            scheduleListFromUI.add(schedule);
        }

        return scheduleListFromUI;
    }
}